using LiveHub.Share.DataModels;
using LiveHub.WebApi.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace LiveHub.WebApi.Controllers;

[Route("api/[controller]/[action]")]
[ApiController]
[TokenActionFilter]
[Authorize]
[Produces("application/json")]
[Consumes("application/json", "multipart/form-data")]
public class GroupController(
    HubContext context,
    IHttpContextAccessor httpContextAccessor)
    : ControllerBase
{
    [HttpGet("{id}")]
    public async Task<ActionResult<GroupModel>> GetData(string id)
    {
        var group = await context.Groups.Include(x => x.Messages)
            .Include(x => x.Users)
            .FirstOrDefaultAsync(x => x.GroupId == id);
        if (group == null) return NotFound();
        return group;
    }

    [HttpGet]
    public async Task<ActionResult<GroupModel[]>> GetGroups()
    {
        var member = httpContextAccessor.HttpContext?.User.GetUser();
        if (member == null) return NotFound();
        member = await context.Users.Include(x => x.Groups).FirstOrDefaultAsync(x => x.UserId == member.UserId);
        return member?.Groups.ToArray() ?? [];
    }

    [HttpPost]
    public async Task<ActionResult<GroupModel>> CreateOrJoinGroup([FromBody] GroupModel model)
    {
        var member = httpContextAccessor.HttpContext?.User.GetUser();
        if (member == null) return NotFound();
        var user = await context.Users.FirstOrDefaultAsync(x => x.UserId == member.UserId);
        if (user == null) return NotFound();
        if (string.IsNullOrEmpty(model.GroupId))
        {
            model.GroupId = model.ToString();
            model.Users.Add(user);
            await context.Groups.AddAsync(model);
        }
        else
        {
            var group = await context.Groups.Include(x => x.Users)
                .FirstOrDefaultAsync(x => x.GroupId == model.GroupId);
            if (group == null) return NotFound();
            if (group.Users.Any(x => x.UserId == user.UserId)) return NotFound();
            group.Users.Add(user);
        }

        await context.SaveChangesAsync();
        return model;
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<GroupModel?>> GetGroupFromId(string id)
    {
        return await context.Groups.FirstOrDefaultAsync(x => x.GroupId == id);
    }

    [HttpPost]
    public async Task<ActionResult> QuitGroup([FromBody] GroupModel model)
    {
        var member = httpContextAccessor.HttpContext?.User.GetUser();
        if (member == null) return NotFound();
        var user = await context.Users.FirstOrDefaultAsync(x => x.UserId == member.UserId);
        if (user == null) return NotFound();
        if (string.IsNullOrEmpty(model.GroupId))
        {
            return NotFound();
        }

        var group = await context.Groups
            .Include(groupModel => groupModel.Users)
            .FirstOrDefaultAsync(x => x.GroupId == model.GroupId);
        if (group == null) return NotFound();
        if (group.Users.All(x => x.UserId != user.UserId)) return NotFound();
        group.Users.Remove(user);
        if (group.Users.Count == 0)
            context.Groups.Remove(group);

        await context.SaveChangesAsync();
        return Ok();
    }
}